package com.espirit.hr;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.espirit.eap.manager.DepartmentService;
import com.espirit.eap.pagelayout.UrlUtil;
import com.espirit.eap.util.BigDecimalUtil;
import com.googlecode.cswish.annotation.GenericType;
import com.googlecode.cswish.annotation.ParamScope;
import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.exception.ApplicationException;
import com.googlecode.cswish.model.PageElements;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.model.ParameterMap;
import com.googlecode.cswish.model.Reference;
import com.googlecode.cswish.oosearch.QLInfo;
import com.googlecode.cswish.struts.spring.GenericService;
import com.googlecode.cswish.struts.spring.SearchCallback;
import com.opensymphony.xwork2.Result;

@Service
public class SalaryItemBaseService {
	@Resource
	GenericService genericService;
	
	@Resource
	DepartmentService departmentService;
	
	@Resource
	HrSettingService hrSettingService;
	
	@Resource
	SalaryService salaryService;
	
	@Resource
	UrlUtil urlUtil;
	
//	@Resource
//	SalaryAdjItemService salaryAdjItemService;
	
	public  PageInfo search(final ParameterMap model, int start, int limit,
    		String sort, String dir, boolean newSearch, Reference<QLInfo> qlInfoRef,
    		@ParamScope(visible=false, value="#ps")PageElements ps ,boolean fromMenu
    		) {
		if (model != null && model.getParameter("employee.id") != null){
			ps.setElementVisible("model.employee.id", false);
		} else {
			ps.setElementVisible("model.employee.id", true);
		}
		SearchCallback callback = departmentService.buildDeptDefaultSearchCallback(model, null, null);
		return genericService.search(model, start, limit, sort, dir, newSearch, qlInfoRef, callback, true, false);
	}
	
	@Rest(type="search")
	public  PageInfo searchRelatedResult(final ParameterMap model, int start, int limit,
    		String sort, String dir, boolean newSearch, Reference<QLInfo> qlInfoRef,
    		@ParamScope(visible=false, value="#ps")PageElements ps ,boolean fromMenu,
    		Reference<Integer> parentId) {
		Integer id = model.getParameter("parent.id", Integer.class);
		if (id != null){
			parentId.set(id);
		} else {
			if (parentId != null){
				model.setParameter("parent.id", parentId.get());
			}
		}
		PageInfo results = search(model, start, limit, sort, dir, newSearch, qlInfoRef, ps, fromMenu);
		return results;
	}
	
	public Result _add(@GenericType Object model, @ParamScope(visible=false, value="#ps")PageElements ps, Reference<Integer> parentId){
    	String param = "salaryId=" + parentId.get();
    	return urlUtil.getUrlResult(SalaryAdjItem.class, "_add", param);
	}
	
	@Transactional
	public void add(@GenericType Object model){
		SalaryItemBase salaryItemBase = (SalaryItemBase) model;
		Salary  salary = salaryService.getCurrentSalary(salaryItemBase.getEmployee().getId());
		if (salary != null){
			
			checkSalaryState(salary);
			
			salaryItemBase.setParent(salary);
			model = genericService.add(model);
			
			BigDecimal origAmount = BigDecimalUtil.getValue(salary.getAmount());
			BigDecimal amount = getDcAmount(BigDecimalUtil.getValue(salaryItemBase.getAmount()), salaryItemBase.getDc());
			amount = amount.add(origAmount);
			salary.setAmount(amount);
			genericService.merge(salary);
		} else {
			throw new ApplicationException("该用户工资不存在，请计算工资后再处理");
		}
	}
	
	public void checkSalaryState(Salary salary){
		if (salary == null) return ;
		Integer state = salary.getState();
		boolean valid = (Salary.STATE_NORMAL.equals(state) );
		if (!valid){
			throw new ApplicationException("当前工资状态为非正常，不能新增修改");
		}
	}
	
	public Result _update(@GenericType Object model, @ParamScope(visible=false, value="#ps")PageElements ps){
		ps.setElementReadOnly("model.acctTerm.id", true);
		ps.setElementReadOnly("model.employee.id", true);
		ps.setElementVisible("model.acctItem.id", true);
		SalaryItemBase salaryItemBase = (SalaryItemBase) model;
		if (salaryItemBase != null && salaryItemBase.getId() != null){
			salaryItemBase = genericService.load(salaryItemBase);
			if (salaryItemBase != null){
				Salary salary = salaryItemBase.getParent();
				salaryItemBase.setEmployee(salary.getEmployee());
				salaryItemBase.setAcctTerm(salary.getAcctTerm());
				ps.setElementReadOnly("model.employee.id", true);
				ps.setElementVisible("model.acctItem.id", false);
			}
			String param = "model.id=" + salaryItemBase.getId();
			if (salaryItemBase instanceof SalaryItem ){
				return urlUtil.getUrlResult(SalaryItem.class, "_update", param);
			} else if (salaryItemBase instanceof SalaryAdjItem){
				return urlUtil.getUrlResult(SalaryAdjItem.class, "_update", param);
			}
		} 
		return null;
	}
	
	@Transactional
	public void update(@GenericType Object model){
		SalaryItemBase salaryItemBase = (SalaryItemBase) model;
		SalaryItemBase orig = genericService.load(SalaryItemBase.class, salaryItemBase.getId());
		BigDecimal origAmount = getDcAmount(BigDecimalUtil.getValue(orig.getAmount()), orig.getDc());
		
		model = genericService.update(model);
		
		Salary  salary = salaryService.getCurrentSalary(salaryItemBase.getEmployee().getId());
		if (salary != null){
			
			checkSalaryState(salary);
			
			BigDecimal amount = getDcAmount(BigDecimalUtil.getValue(salaryItemBase.getAmount()), salaryItemBase.getDc());
			BigDecimal diff = amount.subtract(origAmount);
			
			BigDecimal origSalaryAmount = BigDecimalUtil.getValue(salary.getAmount());
			origSalaryAmount = origSalaryAmount.add(diff);
			salary.setAmount(origSalaryAmount);
			
			genericService.merge(salary);
		} else {
			throw new ApplicationException("该用户工资不存在，请计算工资后再处理");
		}
	}
	
	public void deleteList(List<SalaryItemBase> results){
		if (results == null) return ;
		for(SalaryItemBase salaryItemBase: results){
			if (salaryItemBase == null || salaryItemBase.getId() == null) continue;
			salaryItemBase = genericService.load(SalaryItemBase.class, salaryItemBase.getId());
			if (salaryItemBase != null){
				if (salaryItemBase instanceof SalaryAdjItem){
					BigDecimal amount = getDcAmount(BigDecimalUtil.getValue(salaryItemBase.getAmount()), salaryItemBase.getDc());
					Salary salary = salaryItemBase.getParent();
					if (salary != null){
						BigDecimal salaryAmount = BigDecimalUtil.getValue(salary.getAmount());
						salaryAmount = salaryAmount.subtract(amount);
						salary.setAmount(salaryAmount);
						genericService.merge(salary);
					}
					genericService.delete(salaryItemBase);
				} else {
					throw new ApplicationException("该工资项不能删除!");
				}
			}
		}
	}
	
	public BigDecimal getDcAmount(BigDecimal amount, Integer dc){
		return amount.multiply(BigDecimal.valueOf(dc));
	}
}
